﻿using Modbus.Device;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FlowmeterUI.Models
{
    public delegate void MessagePrintHandler(object sender, string message);
    public class ModbusRTU
    {
		#region 变量
		SerialPort serialPort = new SerialPort();
		ModbusSerialMaster master;
		private static object _lock1 = new object();
		public event MessagePrintHandler MessagePrintEvent;
		#endregion
		#region 实例化
		private static ModbusRTU _instance;
		private static object _lock = new object();
		public static ModbusRTU Instance
		{
			get
			{
				if (ModbusRTU._instance == null)
				{
					object @lock = ModbusRTU._lock;
					lock (@lock)
					{
						if (ModbusRTU._instance == null)
						{
							ModbusRTU._instance = new ModbusRTU();
						}
					}
				}
				return ModbusRTU._instance;
			}
		}
		#endregion
		#region 功能函数
		public bool Connect(string _portName)
		{
			try
			{
				if (this.serialPort.IsOpen)
				{
					if (MessagePrintEvent != null)
					{
						MessagePrintEvent(this, $"PLC串口{_portName}已打开");
					}
					return false;
				}
				else
				{
					this.serialPort.PortName = _portName;
					serialPort.BaudRate = 9600;
					serialPort.DataBits = 8;
					serialPort.Parity = Parity.None;
					serialPort.StopBits = StopBits.One;
					this.serialPort.Open();
					this.serialPort.DiscardInBuffer();
					this.serialPort.DiscardOutBuffer();
					this.serialPort.WriteTimeout = 500;
					this.serialPort.ReadTimeout = 500;

					master = ModbusSerialMaster.CreateRtu(serialPort);
					return true;
				}
			}
			catch (Exception ex)
			{
				if (MessagePrintEvent != null)
				{
					MessagePrintEvent(this, ex.Message);
				}
			}
			return false;
		}
		public void DisConnect()
		{
			try
			{
				this.serialPort.Close();
			}
			catch { }
		}
		public string ReadAsHexString(byte station,ushort add,ushort number = 2)
		{
			ushort[] r = master.ReadHoldingRegisters(station, add, number);
			return string.Join("", from p in r select p.ToString("X4"));
		}
		#endregion
	}
}
